<template>
  <div class="transform-grammar-container">
    <div class="progress-row">
      <!-- 左侧百分比和文字 -->
      <div class="progress-left">
        <div class="progress-percent">{{ progress }}%</div>
        <div class="progress-label">转换进度</div>
      </div>
      <!-- 中间进度条 -->
      <div class="progress-bar-wrap">
        <a-progress
          :percent="progress"
          show-info="false"
          :stroke-color="'#52c41a'"
        />
      </div>
      <!-- 右上角按钮 -->
      <div class="progress-actions">
        <a-button
          @click="isFirstConvert ? handleStart() : (showRangeModal = true)"
          :loading="loadingStates.startConvert"
        >
          {{ isFirstConvert ? "转换" : "重新转换" }}
        </a-button>
        <a-button
          style="margin-left: 16px"
          @click="handleStop"
          :loading="loadingStates.stopConvert"
          >停止</a-button
        >
      </div>
    </div>
    <!-- 时间信息，靠右下 -->
    <div class="progress-times">
      <div style="margin-bottom: 10px">
        转换开始时间：{{ startTime || "-" }}
      </div>
      <div>转换结束时间：{{ endTime || "-" }}</div>
    </div>

    <a-divider />
    <!-- 报告下载按钮 -->
    <div style="margin: 16px 0 0 0">
      <a-button @click="showDownloadModal = true" :disabled="!canDownload" :loading="loadingStates.downloadReport">报告下载</a-button>
    </div>
    <!-- 对象类型统计表 -->
    <a-table
      :columns="columns"
      :data-source="tableData"
      :pagination="false"
      row-key="objType"
      class="object-table"
      style="margin-top: 24px"
    >
      <template #action="{ record }">
        <a-button
          v-if="record.success > 0"
          type="link"
          @click="handleView(record)"
        >查看</a-button>
      </template>
    </a-table>
    <!-- 上一步/下一步按钮 -->
    <div class="flex justify-center" style="margin-top: 32px">
      <a-button
        type="primary"
        @click="prev"
        style="margin-right: 10px"
        :disabled="isConverting || loadingStates.startConvert"
        >上一步</a-button
      >
      <a-button type="primary" @click="next">下一步</a-button>
    </div>
    <!-- 选择转换范围弹窗 -->
    <a-modal
      v-model:visible="showRangeModal"
      title="选择转换范围"
      @ok="handleRangeOk"
      @cancel="showRangeModal = false"
      :confirm-loading="loadingStates.checkFailObjects"
    >
      <a-radio-group v-model:value="rangeOption">
        <a-radio :value="1">仅转换失败的对象</a-radio>
        <a-radio :value="null">重新转换全部对象</a-radio>
      </a-radio-group>
    </a-modal>
    <!-- 下载报告弹窗 -->
    <a-modal v-model:visible="showDownloadModal" title="下载报告" @cancel="showDownloadModal = false" :footer="null">
      <a-table :data-source="reportList" :pagination="false" :show-header="true" row-key="no" :columns="downloadColumns" bordered>
        <template #name="{ record }">
          {{ record.name }}
          <a-tooltip>
            <template #title>{{ record.tip }}</template>
            <InfoCircleOutlined style="margin-left: 4px; color: #999;" />
          </a-tooltip>
        </template>
        <template #action="{ record }">
          <a-button type="link" @click="downloadReport(record.no)" :loading="loadingStates.downloadReport && downloadingNo === record.no">下载</a-button>
        </template>
      </a-table>
      <div style="text-align:right;margin-top:16px;">
        <a-button @click="showDownloadModal = false">关闭</a-button>
      </div>
    </a-modal>
  </div>
</template>

<script setup>
import { ref, onUnmounted, defineEmits, h } from "vue";
import * as http from "@/api/flow/createTask.js";
import { xoneMigration } from "@/api/urlModule";
import { message } from 'ant-design-vue';
import { InfoCircleOutlined } from '@ant-design/icons-vue';

// ====== 1. 关键参数（实际项目中建议通过props、store、路由等传入） ======
const flowId = ref("1751594386615");
const tokenID = window.sessionStorage.getItem('Admin-Token');

// ====== 2. 页面状态 ======
const progress = ref(0); // 进度百分比
const isConverting = ref(false); // 是否正在转换
const isFirstConvert = ref(true); // 是否首次转换
const showRangeModal = ref(false); // 控制弹窗显示
const rangeOption = ref(1); // 弹窗选项，1=仅失败，null=全部
const startTime = ref("");
const endTime = ref("");
const tableData = ref([]); // 表格数据
let ws = null; // WebSocket实例

// ====== 3. 计算属性 ======
const canDownload = ref(false); // 是否可下载报告

// ====== 4. Loading状态 ======
const loadingStates = ref({
  startConvert: false, // 开始转换loading
  checkFailObjects: false, // 检查失败对象loading
  stopConvert: false, // 停止转换loading
  downloadReport: false // 下载报告loading
});

const downloadingNo = ref(null);

// ====== 5. 初始化页面 ======
function resetPage() {
  progress.value = 0;
  isConverting.value = false;
  isFirstConvert.value = true;
  startTime.value = "";
  endTime.value = "";
  canDownload.value = false;
  tableData.value = [
    
  ];
}
resetPage();

// 1. 点击"转换"或"重新转换"按钮
async function handleStart(customRange = null) {
  loadingStates.value.startConvert = true;
  isConverting.value = true;
  startTime.value = new Date().toLocaleString();
  endTime.value = "";
  progress.value = 0;
  // range参数
  const useRange = customRange !== null ? customRange : null;
  try {
    await http.switchSyntax({
      flowId: flowId.value,
      range: useRange,
      tokenID: tokenID.value,
    });
    openWebSocket();
    isFirstConvert.value = false; // 转换后变为"重新转换"
    canDownload.value = false;
  } catch (e) {
    isConverting.value = false;
    message.error("转换接口调用失败");
  } finally {
    loadingStates.value.startConvert = false;
  }
}
// 弹窗确定
async function handleRangeOk() {
  if (rangeOption.value === 1) {
    // 只转换失败对象，先检查是否有失败
    loadingStates.value.checkFailObjects = true;
    try {
      const res = await http.checkExistFail({
        flowId: flowId.value,
        type: 0,
        tokenID: tokenID.value,
      });
      if (!res?.data) {
        message.warning("没有失败的对象");
        return;
      }
    } catch (e) {
      message.error("检查失败对象接口异常");
      return;
    } finally {
      loadingStates.value.checkFailObjects = false;
    }
  }
  showRangeModal.value = false;
  // 重新转换全部对象时清空数据
  if (rangeOption.value === null) {
    resetPage();
  }
  handleStart(rangeOption.value);
}

// 2. WebSocket监听进度和表格
function openWebSocket() {
  console.log(flowId.value);
  // ws地址拼接，参数base64加密
  const wsUrl = `${xoneMigration}SwitchOrMigWebSocket/${encode(JSON.stringify({
    flowID: flowId.value,
    type: 0
  }))}`;
  ws = new window.WebSocket(wsUrl);
  ws.onmessage = (e) => {
    const data = JSON.parse(e.data);
    progress.value = data.progress;
    // 表格数据处理，补全action列
    tableData.value = (data.list || []).map((row) => ({
      ...row,
      action:
        row.success > 0
          ? h(
              "a-button",
              { type: "link", onClick: () => handleView(row) },
              "查看"
            )
          : "",
    }));
    if (data.progress === 100) {
      isConverting.value = false;
      endTime.value = new Date().toLocaleString();
      ws.close();
      canDownload.value = true;
    }
  };
  ws.onerror = () => {
    isConverting.value = false;
    message.error("WebSocket连接失败");
  };
  ws.onclose = () => {
    isConverting.value = false;
  };
}



// 4. 停止（可选，接口待定）
async function handleStop() {
  loadingStates.value.stopConvert = true;
  try {
    await http.stop({
      flowId: flowId.value,
      type: 0,
    });
    if (ws) ws.close();
    isConverting.value = false;
    endTime.value = new Date().toLocaleString();
  } catch (e) {
    message.error("停止转换失败");
  } finally {
    loadingStates.value.stopConvert = false;
  }
}



// 6. 页面卸载时关闭WebSocket
onUnmounted(() => {
  if (ws) ws.close();
});

// ====== 7. 事件定义（与父组件联动） ======
const emit = defineEmits(["save", "next", "prev", "viewObject"]);
const next = () => emit("next");
const prev = () => emit("prev");

// ====== 8. 表格列定义 ======
const columns = [
  { title: "对象类型", dataIndex: "objType", key: "objType", align: "center" },
  { title: "总数", dataIndex: "total", key: "total", align: "center" },
  { title: "跳过", dataIndex: "skip", key: "skip", align: "center" },
  { title: "转换成功", dataIndex: "success", key: "success", align: "center" },
  { title: "转换失败", dataIndex: "fail", key: "fail", align: "center" },
  { title: "剩余量", dataIndex: "surplus", key: "surplus", align: "center" },
  {
    title: "成功率",
    dataIndex: "successRate",
    key: "successRate",
    align: "center",
  },
  {
    title: "操作",
    dataIndex: "action",
    key: "action",
    slots: { customRender: "action" },
    align: "center"
  }
];

// 查看按钮事件（可自定义弹窗或跳转）
function handleView(row) {
  emit('viewObject', 0, row); // 通知父组件，传递当前对象
}

function encode(str) {
  // 对字符串进行编码
  var encode = encodeURI(str);
  // 对编码的字符串转化base64
  var base64 = btoa(encode);
  return base64;
}

// ====== 下载报告弹窗相关 ======
const showDownloadModal = ref(false);
const reportList = [
  { no: 1, name: '转换错误报告', tip: '转换过程中出现的错误明细' },
  { no: 2, name: '匿名化转换错误报告', tip: '匿名化转换时的错误明细' },
  { no: 3, name: '转换风险报告', tip: '转换过程中的风险提示' },
  { no: 4, name: '匿名化转换风险报告', tip: '匿名化转换过程中的风险提示' },
  { no: 5, name: '转换后的SQL解析失败报告', tip: '转换后SQL解析失败明细' },
  { no: 6, name: '匿名化转换后的SQL解析失败报告', tip: '匿名化转换后SQL解析失败明细' }
];
const downloadColumns = [
  { title: '报告名称', dataIndex: 'name', key: 'name', slots: { customRender: 'name' } },
  { title: '操作', dataIndex: 'action', key: 'action', slots: { customRender: 'action' }, align: 'center' }
];
async function downloadReport(no) {
  downloadingNo.value = no;
  loadingStates.value.downloadReport = true;
  try {
    window.open(xoneMigration + 'syntaxSwitchController/download?no=' + no + '&flowId=' + flowId.value + '&tokenID=' + tokenID.value);
  } finally {
    loadingStates.value.downloadReport = false;
    downloadingNo.value = null;
  }
}
</script>

<style scoped>
.transform-grammar-container {
  background: #fff;
  border-radius: 18px;
  padding: 40px 36px 36px 36px;
  /* max-width: 900px; */
  /* margin: 40px auto 0 auto; */
  width: 100%;
  min-height: 400px;
  box-sizing: border-box;
  box-shadow: 0 6px 32px 0 rgba(0, 0, 0, 0.08),
    0 1.5px 4px 0 rgba(0, 0, 0, 0.03);
}
.progress-row {
  display: flex;
  align-items: center;
  width: 100%;
  margin-bottom: 16px;
  position: relative;
}
.progress-left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 120px;
  margin-right: 32px;
}
.progress-percent {
  font-size: 2.5rem;
  font-weight: 800;
  color: #1890ff;
  margin-bottom: 2px;
  letter-spacing: 1px;
  text-shadow: 0 2px 8px #e6f7ff;
}
.progress-label {
  font-size: 1.2rem;
  color: #222;
  font-weight: 500;
  letter-spacing: 1px;
}
.progress-bar-wrap {
  flex: 1;
  margin-top: 8px;
  margin-right: 40px;
}
.progress-bar-wrap .ant-progress-bg {
  height: 14px !important;
  border-radius: 8px !important;
  background: linear-gradient(90deg, #52c41a 0%, #1890ff 100%) !important;
}
.progress-bar-wrap .ant-progress-outer {
  border-radius: 8px !important;
}
.progress-actions {
  display: flex;
  align-items: center;
}
.progress-actions .ant-btn:not(:last-child) {
  margin-right: 16px;
}
.progress-actions .ant-btn:hover {
  background: #1890ff;
  color: #fff;
  border-color: #1890ff;
}
.progress-times {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  margin-top: 12px;
  color: #333;
  font-size: 15px;
  font-weight: 400;
}
.object-table {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.04);
  overflow: hidden;
}
.object-table .ant-table-thead > tr > th {
  background: #f5f7fa;
  font-weight: 700;
  font-size: 1.08rem;
  color: #222;
  text-align: center;
  border-bottom: 2px solid #e6f7ff;
}
.object-table .ant-table-tbody > tr > td {
  text-align: center;
  font-size: 1.05rem;
  padding: 12px 0;
}
.object-table .ant-table-tbody > tr {
  transition: background 0.2s;
}
.object-table .ant-table-tbody > tr:hover {
  background: #e6f7ff;
}
.flex.justify-center {
  margin-top: 32px;
}
.flex.justify-center .ant-btn:hover {
  background: #1890ff;
  color: #fff;
  border-color: #1890ff;
}
</style>
